#pragma once

#include "btBulletCollisionCommon.h"
#include "btBulletDynamicsCommon.h"
#include <Ogre.h>
#include <OIS.h>
#include <vector>

using namespace Ogre;

class OgreObjectState;
class OgreRigidObject;

// -------------------------------------------------------- //
// basic rigid body class
class OgreRigidObject 
{
public:
	SceneNode*         mNode;
	SceneManager*     mManager;
	btRigidBody*       mBody;
	btCollisionShape*  mShape;
	OgreObjectState*   mState;
	btTriangleMesh*    mTriMesh;

	OgreRigidObject(String name, SceneManager *mgr, Vector3 pos, Vector3 scale, Quaternion quat);
	OgreRigidObject(Ogre::SceneNode* node, SceneManager *mgr);
	~OgreRigidObject();
	void createBody(btDynamicsWorld *world, float mass );
	void createCubeBody(btDynamicsWorld *world, Vector3 BoundingBox, float mass );
	void createSphereBody(btDynamicsWorld *world, float r, float mass );
	void createMeshCollider(Ogre::Mesh *ptr, btDynamicsWorld *world, Vector3 scale, float mass);
	void createMeshCollider(Ogre::Mesh *ptr, btDynamicsWorld *world, float mass);
};


// -------------------------------------------------------- //
// Object transforms
class OgreObjectState : public btMotionState
{
	OgreRigidObject *mObject;
public:
	OgreObjectState(OgreRigidObject *parent);
	~OgreObjectState();

	virtual void getWorldTransform(btTransform& worldTrans ) const;
	virtual void setWorldTransform(const btTransform& worldTrans);	
};


// -------------------------------------------------------- //
// Wrapper for adding dynamic physics objects
class EntityWrapper
{
public:
	enum{SHAPE_CUBE, SHAPE_SPHERE, SHAPE_CYLINDER, SHAPE_MESH};
	EntityWrapper(String name, String meshName, btDynamicsWorld* world, SceneManager *mgr, Vector3 pos, Vector3 scale, Quaternion quat, bool staticMesh, float mass);

	EntityWrapper(String name, String meshName, btDynamicsWorld* world, SceneManager *mgr, int type, float mass, Vector3 pos, Vector3 scale, Quaternion quat, long qury = 0x0);
	EntityWrapper(Ogre::SceneNode* node, Ogre::Entity* ent, btDynamicsWorld* world, SceneManager *mgr, int type, float mass, long qury = 0x0);
	~EntityWrapper();


	EntityWrapper* clone();
	OgreRigidObject *getRigidBody();

	void SetFraction(float f){mRigidBody->mBody->setFriction(f);}
	float GetMess(){return mMess;}
	void ChangePhyState(Ogre::Vector3 pos, Ogre::Quaternion q);

private:
	OgreRigidObject*  mRigidBody;
	Entity*           mEnt;
	String            mMeshName;
	btDynamicsWorld*  mWorld;
	SceneManager*     mManager;
	float			  mMess;

	void CreateBody(int type);
};